package bl;

import java.math.BigInteger;
import java.security.InvalidParameterException;
import java.util.Arrays;

public class IntegersNIZKproof implements NIZKproofI {

	BigInteger p1;
	BigInteger p2;
	private int byteLength;

	public IntegersNIZKproof(BigInteger p1, BigInteger p2, int byteLengh) {
		this.p1 = p1;
		this.p2 = p2;
		if (byteLengh % 2 == 1) {
			throw new InvalidParameterException("byteLength must be even");
		}
		this.byteLength = byteLengh;
	}

	public IntegersNIZKproof(IntegersPublicParameters ipp,
			IntegersVEBToken vtoken, BigInteger sc)
			throws IneligibleTypeException {
		// choose random rho
		BigInteger rho = Common.randBigInteger(ipp.G, ipp.GetBitLength());

		this.p1 = ipp.g.modPow(rho, ipp.G);
		BigInteger h = vtoken.CalculateH(p1, ipp);

		// because we use p2 only as the exponent of the generator in G, we can
		// send it modulu the order of G, which is q.
		this.p2 = ((((h.multiply(sc)).mod(ipp.q)).multiply(vtoken.EBtoken))
				.mod(ipp.q)).add(rho).mod(ipp.q);

		this.byteLength = ipp.GetProofLengthBytes();
	}

	public IntegersNIZKproof(byte[] bytes, IntegersPublicParameters ipp) {
		this.byteLength = ipp.GetProofLengthBytes();

		int arrayMidIndex = ipp.GetProofLengthBytes() / 2;
		byte[] p1Bytes = Arrays.copyOfRange(bytes, 0, arrayMidIndex);
		byte[] p2Bytes = Arrays.copyOfRange(bytes, arrayMidIndex,
				ipp.GetProofLengthBytes());

		this.p1 = new BigInteger(p1Bytes);
		this.p2 = new BigInteger(p2Bytes);
	}

	@Override
	public byte[] GetBytes() {
		return Common.concat(
				Common.CreatePaddedBigIntegerBytes(p1, this.byteLength / 2),
				Common.CreatePaddedBigIntegerBytes(p2, this.byteLength / 2));
	}

}
